package impl

import (
	"context"
	"net/http"
	"time"
	"vblog/apps/blog"
	"vblog/common"
)

// 查询文章列表
func (i *impl) QueryBlog(ctx context.Context, in *blog.QueryBlogRequest) (*blog.BlogSet, error) {
	// 提前构造一个blogset.
	blogSet := blog.NewBlogSet()
	// 模拟网络慢
	time.Sleep(1 * time.Second)
	// 需要构造SQL查询
	query := i.db.WithContext(ctx).Model(&blog.Blog{})
	// 模糊查询
	if in.Keywords != "" {
		// %xxxx% ---> *xxxx*
		query = query.Where("content LIKE ?", "%"+in.Keywords+"%")
	}
	if in.Author != "" {
		query = query.Where("author = ?", in.Author)
	}

	// 分页是必传参数. Offset  忽略前面多少个, limit 一页多少个
	err := query.
		// COUNT(*) WHERE XXX
		Count(&blogSet.Total).
		Offset(in.Offset()).
		Limit(in.PageSize).
		// SELECT * FROM ...
		// SELECT * FROM `blogs` WHERE content LIKE '%项目%' LIMIT 20
		Find(&blogSet.Items).
		Error
	if err != nil {
		return nil, err
	}
	// 分页查询的参数流到最后拼凑,因为等下要Count, Count(*) Where xxx, xxx, xxx
	return blogSet, nil
}

func (i *impl) DescribeBlog(ctx context.Context, in *blog.DescribeBlogRequest) (*blog.Blog, error) {
	// 需要构造SQL查询
	query := i.GetDB(ctx)
	ins := blog.NewBlog(blog.NewCreateBlogRequest())
	err := query.Where("id = ?", in.Id).First(ins).Error
	if err != nil {
		return nil, err
	}
	return ins, nil
}

func (i *impl) CreateBlog(ctx context.Context, in *blog.CreateBlogRequest) (*blog.Blog, error) {
	//检查用户的参数
	if err := in.Validate(); err != nil {
		return nil, common.NewApiException(http.StatusBadRequest, err.Error())
	}
	// 生产一个blog对象
	// ins := blog.Blog{
	// 	Meta : &blog.Meta{},
	// 	CreateBlogRequest: &blog.CreateBlogRequest{},
	// }
	// ins.CreateBlogRequest.Extra
	// 代码不具有兼容性

	// 使用构造函数生产一个blog对象
	ins := blog.NewBlog(in)

	// 直接和数据库交互
	// 尽量不用直接这样写? 比如用户提交一个请求,等待过程中又取消了.那么这里无法操作
	// i.db.Save(ins)
	// 加上WithContext之后在Save这样可避免.
	// INSERT INTO `blogs` (`created_at`,`updated_at`,`published_at`,`title`,`author`,`content`,`tags`,`status`)
	// VALUES (1710003706,1710003706,0,'test','test','test','{}','0')
	err := i.db.WithContext(ctx).Save(ins).Error
	if err != nil {
		return nil, common.NewApiException(http.StatusInternalServerError, err.Error())
	}
	// ins := &blog.Blog{}
	// err := i.save(ctx, ins)
	// if err != nil {
	// 	return nil, err
	// }
	return ins, nil
}

func (i *impl) UpdateBlog(ctx context.Context, in *blog.UpdateBlogRequest) (*blog.Blog, error) {

	if err := in.Validate(); err != nil {
		return nil, err
	}

	err := i.GetDB(ctx).Where("id = ?", in.Id).Updates(in.CreateBlogRequest).Error
	if err != nil {
		return nil, err
	}
	// 查询更新后的实例, 方便前端直接进行对象显示
	ins, err := i.DescribeBlog(ctx, in.DescribeBlogRequest)
	if err != nil {
		return nil, err
	}

	return ins, nil
}

func (i *impl) DeleteBlog(ctx context.Context, in *blog.DeleteBlogRequest) (*blog.Blog, error) {
	ins, err := i.DescribeBlog(ctx, in.DescribeBlogRequest)
	if err != nil {
		return nil, err
	}
	err = i.GetDB(ctx).Where("id = ?", in.Id).Delete(ins).Error
	if err != nil {
		return nil, err
	}
	return ins, nil
}
